﻿/*
 *Copyright(C) 2024 by CometGamming All rights reserved.
 *Unity版本：2022.3.43f1c1 
 *作者:程一峰  
 *创建日期: 2024-10-13 
 *模块说明：简易状态机
 *版本: 0.1.0
*/

using Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Warfare.FSM
{
    /// <summary>
    /// 状态机运行器，单个状态机实例
    /// </summary>
    [Serializable]
    public class FSMMachine
    {

        [DisplayAsString, ShowInInspector]
        [LabelText("状态机名")]
        public string Name { get; private set; }

        /// <summary>
        /// 状态机根节点
        /// </summary>
        public FSMState Root { get; private set; }

        /// <summary>
        /// 当前节点；
        /// </summary>
        [DisplayAsString, ShowInInspector]
        [LabelText("当前节点")]
        public FSMState CurrentNode { get; private set; }

        /// <summary>
        /// 上下文；
        /// </summary>
        public I_FSMContext Context { get; private set; }

        /// <summary>
        /// 运行对象；
        /// </summary>
        public I_FSMActor Actor { get; private set; }

        /// <summary>
        /// 已经初始化
        /// </summary>
        [DisplayAsString, ShowInInspector]
        [LabelText("初始化")]
        public bool Inited { get; private set; }

        public void Init(I_FSMContext context, I_FSMActor actor)
        {
            Context = context;
            Actor = actor;
            Inited = true;
#if UNITY_EDITOR
            Debug.Log($"[FSM] 状态机{Name}初始化完成：{context}, {actor}");
#endif
        }

        public void Run(FSMState state = null)
        {
            CurrentNode = state == null ? Root : state;
            CurrentNode.OnEnter();
#if UNITY_EDITOR
            Debug.Log($"[FSM] 状态机{Name} 开始运行：{CurrentNode?.Name}");
#endif
        }

        public void Update(float deltaTime)
        {
            CurrentNode?.Update(deltaTime);
        }

        #region 状态机子状态管理

        private Dictionary<int, FSMState> m_DictAllStates = new Dictionary<int, FSMState>() { };

        internal FSMState FindFSMState(int fsmIndex)
        {
            if (m_DictAllStates.TryGetValue(fsmIndex, out FSMState state))
            {
                if (state != null)
                    return state;
#if UNITY_EDITOR
                Debug.LogWarning($"【FSM】： 状态机_{Name} 没有配置节点ID：{fsmIndex} ");
#endif
            }
            return Root;
        }

        #endregion

        #region 状态机的创建

        public static FSMMachine Create(FSMAsset asset, I_FSMContext context, I_FSMActor actor)
        {
            var machine = Create(asset);
            machine.Init(context, actor);
            return machine;
        }

        /// <summary>
        /// 创建一个状态机；
        /// </summary>
        /// <param name="asset"></param>
        /// <returns></returns>
        public static FSMMachine Create(FSMAsset asset)
        {
            if (asset == null)
            {
                Debug.LogError("【FSM】传入的状态机配置为空！");
                return null;
            }

            FSMMachine machine = new FSMMachine();
            machine.CraeteMachine_Interal(asset);
            return machine;
        }

        internal void CraeteMachine_Interal(FSMAsset asset)
        {
            Root = CreateFSMState(asset.RootNode);
            Name = $"{asset.name}_{asset.Descripe}";
            foreach (var node in asset.ListNodes)
            {
                if (node == null)
                    continue;

                var state = CreateFSMState(node);
                if (state == null)
                    continue;

                //存入字典；
                m_DictAllStates[state.ConfigID] = state;
            }
#if UNITY_EDITOR
            Debug.Log($"【FSM】{asset.name} 创建状态机完成：{m_DictAllStates.Count}");
#endif
        }

        internal FSMState CreateFSMState(FSMNode node)
        {
            if (node == null)
            {
                Debug.LogError("传入的节点对象为空！");
                return null;
            }
            var state = new FSMState(this, node);
            return state;
        }

        #endregion


    }
}